package cn.school.demo.repository

import android.annotation.SuppressLint
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import cn.school.demo.pojo.*
import cn.school.demo.util.HttpApi
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonDeserializer
import com.google.gson.reflect.TypeToken
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId


class HistoryRepository {
    private val httpApi: HttpApi

    init {
        val retrofit =
            Retrofit.Builder().baseUrl(DataRepository.BASEURL).addConverterFactory(
                GsonConverterFactory.create()
            )
                .build()
        httpApi = retrofit.create(HttpApi::class.java)
    }

    fun getUserBrowseInfo(id: Int): LiveData<MutableList<ArticleBrowse>> {
        val responseLiveData = MutableLiveData<MutableList<ArticleBrowse>>()
        httpApi.getUserBrowseInfo(mapOf("sfNumber" to id)).enqueue(object : Callback<Result> {
            @SuppressLint("NewApi")
            override fun onResponse(call: Call<Result>, response: Response<Result>) {
                response.body()?.let {
                    when (it.success) {
                        true -> {
                            try {
                                val articleList = GsonUtils.fromJson<MutableList<Article>>(
                                    it.data["article"].toString(),
                                    object : TypeToken<MutableList<Article>>() {}.type
                                )
                                val timesList = GsonUtils.fromJson<MutableList<Times>>(
                                    it.data["times"].toString(),
                                    object : TypeToken<MutableList<Times>>() {}.type
                                )
                                if (articleList.isNotEmpty() && timesList.isNotEmpty()) {
                                    val articleBrowseList = mutableListOf<ArticleBrowse>()
                                    var i = 0
                                    timesList.forEach { time ->
                                        articleBrowseList.add(
                                            ArticleBrowse(
                                                null,
                                                time
                                            )
                                        )
                                        val num = i + time.frequency
                                        while (i < num) {
                                            articleBrowseList.add(
                                                ArticleBrowse(
                                                    articleList[i],
                                                    time
                                                )
                                            )
                                            i++
                                        }
                                    }
                                    responseLiveData.value = articleBrowseList
                                } else {
                                    LogUtils.e("数据解析失败！")
                                }
                            } catch (e: Error) {
                                e.printStackTrace()
                            }
                        }
                        else -> {
                            responseLiveData.value = mutableListOf()
                        }
                    }
                } ?: LogUtils.e("用户浏览记录http返回值为空！")
            }

            override fun onFailure(call: Call<Result>, t: Throwable) {
                LogUtils.e(t)
            }
        })
        return responseLiveData
    }

    fun deleteUserBrowseInfo(browse: MutableList<Browse>): LiveData<Boolean> {
        val responseLiveData = MutableLiveData<Boolean>()
        val map = mapOf("browse" to GsonUtils.toJson(browse))
        httpApi.deleteUserBrowseInfo(map).enqueue(object : Callback<Result> {
            override fun onResponse(call: Call<Result>, response: Response<Result>) {
                response.body()?.let {
                    LogUtils.d(it.toString())
                    responseLiveData.value = it.success
                } ?: LogUtils.e("删除浏览记录http返回值为空！")
            }

            override fun onFailure(call: Call<Result>, t: Throwable) {
                LogUtils.e(t)
            }
        })
        return responseLiveData
    }

    fun saveBrowseInfo(userId: Int, articleId: Int): LiveData<Boolean> {
        val responseLiveData = MutableLiveData<Boolean>()
        httpApi.saveBrowseInfo(mapOf("sfNumber" to userId, "articleId" to articleId))
            .enqueue(object : Callback<Result> {
                override fun onResponse(call: Call<Result>, response: Response<Result>) {
                    response.body()?.let {
                        LogUtils.d(it.message)
                        responseLiveData.value = it.success
                    } ?: LogUtils.e("保存浏览记录http返回值为空！")
                }

                override fun onFailure(call: Call<Result>, t: Throwable) {
                    LogUtils.e(t)
                }
            })
        return responseLiveData
    }

    fun getAnswerHistory(id: Int): LiveData<Result?> {
        val responseLiveData = MutableLiveData<Result?>()
        httpApi.getAnswerHistory(mapOf("sfNumber" to id)).enqueue(object : Callback<Result> {
            override fun onResponse(call: Call<Result>, response: Response<Result>) {
                response.body()?.let {
                    responseLiveData.value = it
                } ?: let {
                    LogUtils.e("获得答题记录http返回值为空！")
                    responseLiveData.value = null
                }
            }

            override fun onFailure(call: Call<Result>, t: Throwable) {
                LogUtils.e(t)
            }

        })
        return responseLiveData
    }
}